﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using SwiftMVVM.ViewModel;
using System.Windows;

namespace SwiftMVVM.ChangeTracking
{
    /// <summary>
    /// Weak EventManager implementation for the PropertyNotificationsSent Event
    /// We are using WeakEvents here because we do not want out listener 
    /// to keep the object alive
    /// </summary>
    internal class PropertyNotificationsSentEventManager : WeakEventManager
    {
        /// <summary>
        /// We do not want the user to be able to instantiate this object
        /// </summary>
        private PropertyNotificationsSentEventManager() { }

        /// <summary>
        /// Adds a listener for the for PropertyChanging event 
        /// </summary>
        /// <param name="source">The tree that will be raising the routed event</param>
        public static void AddListener(DependentBindingObject source, IWeakEventListener listener)
        {
            CurrentManager.ProtectedAddListener(source, listener);
        }

        /// <summary>
        /// Removes a listener from the for PropertyChanging event 
        /// </summary>
        /// <param name="source">The tree that will be raising the routed event</param>
        public static void RemoveListener(DependentBindingObject source, IWeakEventListener listener)
        {
            CurrentManager.ProtectedRemoveListener(source, listener);
        }

        /// <summary>
        /// Starts listening for the event being managed. 
        /// After the StartListening method is first called, 
        /// the manager should be in the state of calling DeliverEvent or 
        /// DeliverEventToList whenever the relevant event from the 
        /// provided source is handled.
        /// </summary>
        /// <param name="source">The source to begin listening on.</param>
        protected override void StartListening(object source)
        {
            ((DependentBindingObject)source).PropertyNotificationsSent +=
            new EventHandler<PropertyChangedEventArgs>(
                dependentBindingObject_PropertyNotificationsSent);
        }

        void dependentBindingObject_PropertyNotificationsSent(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            base.DeliverEvent(sender, e);
        }

        /// <summary>
        /// When overridden in a derived class, stops listening on the provided source for the event being managed.
        /// </summary>
        /// <param name="source">The source to stop listening on.</param>
        protected override void StopListening(object source)
        {
            ((DependentBindingObject)source).PropertyNotificationsSent -=
            new EventHandler<PropertyChangedEventArgs>(
                dependentBindingObject_PropertyNotificationsSent);
        }

        /// <summary>
        /// Returns the WeakEventManager implementation that is used for the provided type.
        /// </summary>
        private static PropertyNotificationsSentEventManager CurrentManager
        {
            get
            {
                Type managerType = typeof(PropertyNotificationsSentEventManager);
                var currentManager = (PropertyNotificationsSentEventManager)WeakEventManager.
                    GetCurrentManager(managerType);

                if (currentManager == null)
                {
                    currentManager = new PropertyNotificationsSentEventManager();
                    WeakEventManager.SetCurrentManager(managerType, currentManager);
                }
                return currentManager;
            }
        }
    }
}
